<template>
  <div class="health-bar-container" :class="{ 'critical': isCritical, 'damaged': isDamaged }">
    <div class="health-label">
      <span class="label-text">生命值</span>
      <span class="health-text">{{ currentHealth }}/{{ maxHealth }}</span>
    </div>
    
    <div class="health-bar-wrapper">
      <div class="health-bar">
        <div 
          class="health-fill"
          :style="{ 
            width: healthPercentage + '%',
            backgroundColor: healthColor
          }"
        ></div>
        
        <!-- 生命值段落指示器 -->
        <div class="health-segments">
          <div 
            v-for="n in healthSegments"
            :key="n"
            class="health-segment"
            :style="{ left: ((n - 1) * segmentWidth) + '%' }"
          ></div>
        </div>
      </div>
      
      <!-- 伤害动画效果 -->
      <div 
        v-if="showDamageEffect" 
        class="damage-overlay"
        :class="{ 'show': damageAnimating }"
      ></div>
    </div>

    <!-- 生命值图标 -->
    <div class="health-icons">
      <div 
        v-for="n in maxLives"
        :key="n"
        class="health-icon"
        :class="{ 
          'active': n <= currentLives,
          'lost': n > currentLives && lostLifeAnimation === n
        }"
      >
        <i class="icon-heart"></i>
      </div>
    </div>

    <!-- 低生命值警告 -->
    <div v-if="isCritical" class="critical-warning">
      <i class="icon-warning"></i>
      <span>生命值危险！</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue'

/**
 * 生命值条组件
 * 显示角色生命值，支持伤害动画和危险状态提示
 * @component
 * @example
 * <HealthBar 
 *   :current-health="75" 
 *   :max-health="100"
 *   :current-lives="2"
 *   :max-lives="3"
 * />
 */

interface Props {
  /** 当前生命值 */
  currentHealth?: number
  /** 最大生命值 */
  maxHealth?: number
  /** 当前生命数 */
  currentLives?: number
  /** 最大生命数 */
  maxLives?: number
  /** 危险阈值（百分比） */
  criticalThreshold?: number
  /** 是否显示伤害效果 */
  showDamageEffect?: boolean
  /** 伤害动画持续时间（毫秒） */
  damageAnimationDuration?: number
}

interface Emits {
  /** 生命值变为危险状态 */
  (e: 'critical-health'): void
  /** 生命值耗尽 */
  (e: 'health-depleted'): void
  /** 失去一条生命 */
  (e: 'life-lost'): void
}

const props = withDefaults(defineProps<Props>(), {
  currentHealth: 100,
  maxHealth: 100,
  currentLives: 3,
  maxLives: 3,
  criticalThreshold: 25,
  showDamageEffect: true,
  damageAnimationDuration: 500
})

const emit = defineEmits<Emits>()

// 响应式数据
const isDamaged = ref(false)
const damageAnimating = ref(false)
const lostLifeAnimation = ref(0)
const previousHealth = ref(props.currentHealth)
const previousLives = ref(props.currentLives)

// 计算属性
const currentHealth = computed(() => Math.max(0, props.currentHealth))
const maxHealth = computed(() => props.maxHealth)
const currentLives = computed(() => Math.max(0, props.currentLives))
const maxLives = computed(() => props.maxLives)

const healthPercentage = computed(() => {
  return Math.max(0, Math.min(100, (currentHealth.value / maxHealth.value) * 100))
})

const isCritical = computed(() => {
  return healthPercentage.value <= props.criticalThreshold
})

const healthColor = computed(() => {
  const percentage = healthPercentage.value
  if (percentage > 60) {
    return '#4CAF50' // $success-color
  } else if (percentage > 30) {
    return '#FFC107' // $warning-color
  } else {
    return '#F44336' // $danger-color
  }
})

const healthSegments = computed(() => {
  return Math.max(1, Math.floor(maxHealth.value / 25))
})

const segmentWidth = computed(() => {
  return 100 / healthSegments.value
})

/**
 * 播放伤害动画
 */
const playDamageAnimation = (): void => {
  if (!props.showDamageEffect) return

  isDamaged.value = true
  
  nextTick(() => {
    damageAnimating.value = true
    
    setTimeout(() => {
      damageAnimating.value = false
      isDamaged.value = false
    }, props.damageAnimationDuration)
  })
}

/**
 * 播放失去生命动画
 * @param lifeIndex - 失去的生命索引
 */
const playLifeLostAnimation = (lifeIndex: number): void => {
  lostLifeAnimation.value = lifeIndex
  
  setTimeout(() => {
    lostLifeAnimation.value = 0
  }, 1000)
}

// 监听生命值变化
watch(() => props.currentHealth, (newHealth, oldHealth) => {
  if (newHealth < (oldHealth || 0)) {
    playDamageAnimation()
  }
  
  if (newHealth <= 0 && (oldHealth || 0) > 0) {
    emit('health-depleted')
  }
  
  previousHealth.value = newHealth
}, { immediate: false })

// 监听生命数变化
watch(() => props.currentLives, (newLives, oldLives) => {
  if (newLives < (oldLives || 0)) {
    const lostLife = (oldLives || 0)
    playLifeLostAnimation(lostLife)
    emit('life-lost')
  }
  
  previousLives.value = newLives
}, { immediate: false })

// 监听危险状态
watch(isCritical, (critical) => {
  if (critical) {
    emit('critical-health')
  }
})
</script>

<style lang="scss" scoped>
.health-bar-container {
  display: flex;
  flex-direction: column;
  gap: $spacing-sm;
  padding: $spacing-md;
  background: rgba(0, 0, 0, 0.8);
  border-radius: $border-radius-md;
  color: white;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: $transition-normal;

  &.critical {
    animation: criticalPulse 1s ease-in-out infinite;
    border-color: $danger-color;
  }

  &.damaged {
    animation: damageShake 0.3s ease-in-out;
  }

  .health-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .label-text {
      font-size: 0.75rem;
      opacity: 0.8;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    
    .health-text {
      font-size: 0.875rem;
      font-weight: bold;
      font-family: 'Courier New', monospace;
    }
  }

  .health-bar-wrapper {
    position: relative;
    
    .health-bar {
      width: 100%;
      height: 12px;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 6px;
      overflow: hidden;
      position: relative;

      .health-fill {
        height: 100%;
        background: $success-color;
        transition: width 0.3s ease, background-color 0.3s ease;
        border-radius: 6px;
        position: relative;

        &::after {
          content: '';
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background: linear-gradient(90deg, 
            transparent 0%, 
            rgba(255, 255, 255, 0.3) 50%, 
            transparent 100%);
          animation: healthShimmer 2s ease-in-out infinite;
        }
      }

      .health-segments {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        pointer-events: none;

        .health-segment {
          position: absolute;
          top: 0;
          bottom: 0;
          width: 1px;
          background: rgba(255, 255, 255, 0.3);
        }
      }
    }

    .damage-overlay {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: $danger-color;
      opacity: 0;
      border-radius: 6px;
      transition: opacity 0.1s ease;

      &.show {
        opacity: 0.6;
      }
    }
  }

  .health-icons {
    display: flex;
    gap: $spacing-xs;
    justify-content: center;

    .health-icon {
      width: 20px;
      height: 20px;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: $transition-normal;

      i {
        font-size: 16px;
        color: rgba(255, 255, 255, 0.3);
        transition: $transition-normal;
      }

      &.active i {
        color: $danger-color;
        text-shadow: 0 0 8px rgba($danger-color, 0.6);
      }

      &.lost {
        animation: lifeLost 1s ease-out;
      }
    }
  }

  .critical-warning {
    display: flex;
    align-items: center;
    gap: $spacing-xs;
    justify-content: center;
    color: $danger-color;
    font-size: 0.75rem;
    font-weight: bold;
    text-transform: uppercase;
    animation: warningBlink 0.5s ease-in-out infinite alternate;

    i {
      font-size: 12px;
    }
  }
}

// 动画定义
@keyframes criticalPulse {
  0%, 100% {
    box-shadow: 0 0 0 rgba($danger-color, 0);
  }
  50% {
    box-shadow: 0 0 20px rgba($danger-color, 0.6);
  }
}

@keyframes damageShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

@keyframes healthShimmer {
  0%, 100% { transform: translateX(-100%); }
  50% { transform: translateX(100%); }
}

@keyframes lifeLost {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.5);
    opacity: 0.5;
  }
  100% {
    transform: scale(0.8);
    opacity: 0.3;
  }
}

@keyframes warningBlink {
  0% { opacity: 1; }
  100% { opacity: 0.5; }
}

// 图标样式
.icon-heart::before { content: '❤️'; }
.icon-warning::before { content: '⚠️'; }

// 响应式设计
@media (max-width: $breakpoint-md) {
  .health-bar-container {
    padding: $spacing-sm;
    
    .health-label {
      .label-text {
        font-size: 0.625rem;
      }
      
      .health-text {
        font-size: 0.75rem;
      }
    }
    
    .health-bar-wrapper .health-bar {
      height: 10px;
    }
    
    .health-icons .health-icon {
      width: 16px;
      height: 16px;
      
      i {
        font-size: 12px;
      }
    }
  }
}
</style>